/**
 * 
 */
package fr.upvm.lem3.vm3d.ui.swing.dataload;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.Serializable;
import java.nio.file.Paths;
import java.util.EventListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import fr.upvm.lem3.vm3d.ui.swing.frontend.MainGUI;


/**
 * This class represent a dialog which help to load cft file(s) or lem3 file in the purpose the render the contained data into a 3d volume form
 *******************************************************************
 *DataLoader.java
 *19.02.2012
 *@author Guy Nougouapi
 *******************************************************************
 *
 *******************************************************************
 */
public class DataLoader extends JDialog implements Serializable , EventListener{

	/**
	 * 
	 */
	private static final long serialVersionUID = -7310587623789336203L;
	public static String CURRENT_DIRECTORY_PATH = ".";    			// Save the last opened directory path
	
	private static String APPLY_BTN_TEXT = "Apply";
	private static String APPLY_BTN_TOOlTIP_TEXT = "Click to vizualize the loaded data";
	private static String CLOSE_BTN_TEXT = "Close";
	private static String CLOSE_BTN_TOOLTIP_TEXT = " close the current window";
	private static String TABBEDPANE_LEM3_TOOLTIP_TEXT = "Load lem3 file";
	private static String TABBEDPANE_CTF_TOOLTIP_TEXT = "Load ctf file(s)";
	private static String LEM3_TAB = "Lem3 ";
	private static String CTF_TAB = "Ctf  ";
	
	
	private JTabbedPane tabbedpane;
	private Lem3DataLoader lem3dataLoader;
	private CtfDataLoader  ctfDataLoader;
	private JPanel 		btnPanel;
	
	JFileChooser filechooser;
	
	private JButton applyBtn;
	private JButton closeBtn;
	
	private MainGUI parentFrame;
	
	
	private DataLoadController controller;
	
	public  DataLoader(MainGUI parentFrame , String title, boolean modal){
		super(parentFrame, title, modal);
		this.controller = new DataLoadController(this);
		this.parentFrame = parentFrame;
//		this.setAlwaysOnTop(true);			//this window will always be above other windows
		this.setResizable(true);
		//set his location the screen whiting his parent frame
		Point point=getParentFrame().getLocationOnScreen();
		int frameHeigt = getParentFrame().getHeight();
		int frameWidth = getParentFrame().getWidth();
		Point center = new Point(frameWidth/2,frameHeigt/2);
		setLocation((int)(point.x + frameWidth * 0.10),(int)(point.y + frameHeigt*0.10));
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				// TODO Auto-generated method stub
				close();
			}
		});
		this.setPreferredSize(new Dimension((int)Math.abs(frameWidth - frameHeigt*0.30 ), (int)Math.abs(frameHeigt - frameHeigt*0.20 )));
		setDefaultCloseOperation(0);
		pack();
		initComponents();
	}
	/**
	 * 
	 */
	private JFrame parent;
	public DataLoader(JFrame frame,String title, boolean modal){
		super(frame, title, modal);
		this.controller = new DataLoadController(this);
		this.parent = frame;
		this.setResizable(true);
		//set his location the screen whiting his parent frame
		Point point=frame.getLocationOnScreen();
		int frameHeigt = frame.getHeight();
		int frameWidth = frame.getWidth();
		Point center = new Point(frameWidth/2,frameHeigt/2);
		setLocation((int)(point.x + frameWidth * 0.10),(int)(point.y + frameHeigt*0.10));
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				// TODO Auto-generated method stub
				close();
			}
		});
		this.setPreferredSize(new Dimension((int)Math.abs(frameWidth - frameHeigt*0.30 ), (int)Math.abs(frameHeigt - frameHeigt*0.20 )));
		setDefaultCloseOperation(0);
		pack();
		initComponents();
	}

	private void initComponents(){
		JPanel rPanel = new JPanel();
		rPanel.setLayout(new BoxLayout(rPanel, BoxLayout.PAGE_AXIS));
		rPanel.add(getTabbedpane());
		rPanel.add(getBtnPanel());
		this.add(rPanel);
	}
  
	/**
	 * @return the tabbedPane
	 */
	public  JTabbedPane getTabbedpane() {
		if(tabbedpane == null){
			UIManager.put("TabbedPane.selected", Color.white);   //color the selected tab in white
			tabbedpane = new JTabbedPane(JTabbedPane.TOP);
			
			CtfDataLoader ctf = getCtfDataLoader();
			JScrollPane scrlPane2 = new JScrollPane(ctf);
			tabbedpane.addTab(ctf.getName(),scrlPane2);
			tabbedpane.setMnemonicAt(0, KeyEvent.VK_C);
			tabbedpane.setToolTipTextAt(0, TABBEDPANE_CTF_TOOLTIP_TEXT);
			
			Lem3DataLoader lem3 = getLem3dataLoader();
			JScrollPane scrlPane = new JScrollPane(lem3);
			tabbedpane.addTab(lem3.getName(),scrlPane);
			tabbedpane.setMnemonicAt(1, KeyEvent.VK_L);
			tabbedpane.setToolTipTextAt(1, TABBEDPANE_LEM3_TOOLTIP_TEXT);
			
			tabbedpane.setSelectedIndex(0);	//set the component on the index 0 has selected
			tabbedpane.setOpaque(true);
		}
			
		return tabbedpane;
	}
	/**
	 * @param tabbedpane the tabbedPane to set
	 */
	public  void setTabbedpane(JTabbedPane tabbedpane) {
		this.tabbedpane = tabbedpane;
	}

	/**
	 * @return the lem3dataLoader
	 */
	public Lem3DataLoader getLem3dataLoader() {
		if (lem3dataLoader == null){
			lem3dataLoader = new Lem3DataLoader(LEM3_TAB, this.getController());
			//
			this.getController().setLEM3Controller(lem3dataLoader.getController());
		}
		return lem3dataLoader;
	}

	/**
	 * @param lem3dataLoader the lem3dataLoader to set
	 */
	public void setLem3dataLoader(Lem3DataLoader lem3dataLoader) {
		this.lem3dataLoader = lem3dataLoader;
	}

	/**
	 * @return the ctfDataLoader
	 */
	public  CtfDataLoader getCtfDataLoader() {
		if (ctfDataLoader == null){
			ctfDataLoader = new CtfDataLoader(CTF_TAB, this.getController());
			
			//the controller of the dataLoader hold  this as reference to the CtfDataloader throw his controller 
			this.getController().setCTFController(ctfDataLoader.getController());
		}
		return ctfDataLoader;
	}

	/**
	 * @param ctfDataLoader the ctfDataLoader to set
	 */
	public  void setCtfDataLoader(CtfDataLoader ctfDataLoader) {
		this.ctfDataLoader = ctfDataLoader;
	}

	/**
	 * @return the btnPanel
	 */
	public  JPanel getBtnPanel() {
		if (btnPanel == null) {
			btnPanel = new JPanel();
			btnPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
			btnPanel.setPreferredSize(new Dimension(0, 50));
			btnPanel.setLayout(new BoxLayout(btnPanel, BoxLayout.X_AXIS));
			btnPanel.add(Box.createHorizontalGlue());
			btnPanel.add(getApplyBtn());
			btnPanel.add(Box.createRigidArea(new Dimension(20,0)));
			btnPanel.add(getCloseBtn());
			btnPanel.add(Box.createRigidArea(new Dimension(3,0)));
			btnPanel.setOpaque(true);
			
		}
		return btnPanel;
	}

	/**
	 * @param btnPanel the btnPanel to set
	 */
	public  void setBtnPanel(JPanel btnPanel) {
		this.btnPanel = btnPanel;
	}

	/**
	 * @return the applyBtn
	 */
	public  JButton getApplyBtn() {
		if(applyBtn== null){
			applyBtn= new JButton();
			applyBtn.setFont(new Font("Dialog", Font.BOLD, 14));
			applyBtn.setToolTipText(APPLY_BTN_TOOlTIP_TEXT);
			applyBtn.setText(APPLY_BTN_TEXT);
			applyBtn.setAlignmentX(Component.CENTER_ALIGNMENT);
			applyBtn.setAlignmentY(Component.CENTER_ALIGNMENT);
			applyBtn.setFocusable(false);
			applyBtn.setEnabled(false);
			applyBtn.setPreferredSize(new Dimension(80, 30));
			applyBtn.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					handleLoadedData(e);
					//after this operation close the window
					applyBtn.setEnabled(false);
					dispose();
				}
			});
		}
		return applyBtn;
	}

	/**
	 * @param applyBtn the applyBtn to set
	 */
	public  void setApplyBtn(JButton applyBtn) {
		this.applyBtn = applyBtn;
	}
	
	/**
	 * Handle the action occurred by click the apply button
	 * @param event
	 */
	private void handleLoadedData( ActionEvent event){
//		JButton btn =(JButton)event.getSource();
		getController().handleLoadedData(getTabbedpane().getSelectedIndex());
	}
	/**
	 * @return the closeBtn
	 */
	public JButton getCloseBtn() {
		if(closeBtn== null){
			closeBtn= new JButton();
			closeBtn.setFont(new Font("Dialog", Font.BOLD, 14));
			closeBtn.setToolTipText(CLOSE_BTN_TOOLTIP_TEXT);
			closeBtn.setText(CLOSE_BTN_TEXT);
			closeBtn.setAlignmentX(Component.CENTER_ALIGNMENT);
			closeBtn.setAlignmentY(Component.CENTER_ALIGNMENT);
			closeBtn.setFocusable(false);
			closeBtn.setPreferredSize(new Dimension(80, 30));
			closeBtn.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					close();
				}
			});
		}
	
		return closeBtn;
	}
	
	/**
	 * @param closeBtn the closeBtn to set
	 */
	public void setCloseBtn(JButton closeBtn) {
		this.closeBtn = closeBtn;
	}
	
	/**
	 * close this frame. this method will not dispose this window but Just hide it.
	 * @param event
	 */
	private void close(){
		getController().close();
	}

	/**
	 * @return the parentFrame
	 */
	public  MainGUI getParentFrame() {
		return parentFrame;
	}

	/**
	 * @param parentFrame the parentFrame to set
	 */
	public  void setParentFrame(MainGUI parentFrame) {
		this.parentFrame = parentFrame;
	}

	/**
	 * @return the controller
	 */
	public  DataLoadController getController() {
		return controller;
	}

	/**
	 * @param controller the controller to set
	 */
	public void setController(DataLoadController controller) {
		this.controller = controller;
	}
	
	/**
	 * 
	 * @return
	 */
	public JFileChooser getFileChooser(String path){
		String ph;
		if(path.isEmpty()){
			ph  = CURRENT_DIRECTORY_PATH;
		}else{
			ph = path;
		}
		if(filechooser == null){	
			filechooser = new JFileChooser(ph);
			filechooser.setDialogTitle(filechooser.getCurrentDirectory().getPath());
			// Turn off 'All Files' capability of file chooser,
			// so only our custom filter is used.
			filechooser.setAcceptAllFileFilterUsed(false);
			
			//display the directory name as title for the file chooser dialog
			filechooser.addPropertyChangeListener(new PropertyChangeListener() {
				@Override
				public void propertyChange(PropertyChangeEvent evt) {
					 if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(evt.getPropertyName())) {
		    	            filechooser.setDialogTitle(filechooser.getCurrentDirectory().getAbsolutePath());
		    	        }
		    	    }
			});
		}else{
			filechooser.setSelectedFile(new File(ph));
		}
		return filechooser;	
	}
	/**
	 * 
	 * @param filechooser
	 */
	public void setFileChooser( JFileChooser filechooser){
		this.filechooser = filechooser;
	}
	/**
	 * make the window visible
	 */
	public void display() {
		if(!isDisplayed())
			this.setVisible(true);
	}
	
	/**
	 * check if this window is visible
	 * @return
	 */
	private boolean isDisplayed(){
		return this.isVisible();
	}
	
	/**
	 * test this window class
	 */
	public static void main(String[] arg){
		
		javax.swing.SwingUtilities.invokeLater(
			new Runnable() {
				public void run() {
					JFrame frame = new JFrame();
					frame.setSize(800, 550);
					frame.setLocationRelativeTo(null);
					frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
					frame.setVisible(true);
					DataLoader loader = new DataLoader(frame,"Ohne",true);
					loader.setVisible(true);
				}
				}
			);
	}
}
